import base64
import random
import string


base32_index = {
    0: 'A',
    1: 'B',
    2: 'C',
    3: 'D',
    4: 'E',
    5: 'F',
    6: 'G',
    7: 'H',
    8: 'I',
    9: 'J',
    10: 'K',
    11: 'L',
    12: 'M',
    13: 'N',
    14: 'O',
    15: 'P',
    16: 'Q',
    17: 'R',
    18: 'S',
    19: 'T',
    20: 'U',
    21: 'V',
    22: 'W',
    23: 'X',
    24: 'Y',
    25: 'Z',
    26: '2',
    27: '3',
    28: '4',
    29: '5',
    30: '6',
    31: '7',
}


def char_2_ascii(c):
    # 字符串转ascii码
    return ord(c)


def fill_bin(number, nbits, mode='right'):
    # 二进制补齐位数
    if mode == 'right':
        return number.rjust(nbits, '0')
    else:
        return number.ljust(nbits, '0')


def dec_2_bin(number):
    # 十进制转二进制(补齐八位)
    return fill_bin(bin(number)[2:], 8)


def bin_2_dec(number):
    # 二进制转十进制
    return int(number, 2)


def dec_2_base32(number):
    # 十进制转base32码
    return base32_index[number]


def string_2_base32(string):
    bins = ''
    for s in string:
        _ascii = char_2_ascii(s)
        bins += dec_2_bin(_ascii)

    i = 0
    base32s = ''
    _bins = ''
    while i <= len(bins) - 1:
        _bin = fill_bin(bins[i:i+5], 5, mode='left')
        _bins += _bin
        _dec = bin_2_dec(_bin)
        base32s += dec_2_base32(_dec)
        i += 5

    subfix = 5 - int(len(_bins) % 40 / 8)
    print(subfix)
    return base32s + subfix * '='


def test_base32():
    # 测试算法
    test_string = list(string.printable)
    n = len(test_string)
    for i in range(1000):
        # 随机测试1000次

        # 随机字符串长度
        string_len = random.randint(1, n)
        random.shuffle(test_string)
        s = ''.join(test_string[:string_len])
        test = string_2_base32(s)
        check = base64.b32encode(s.encode('utf-8')).decode('utf-8')
        if test != check:
            print('s=({})'.format(s))
            print('test={}'.format(test))
            print('check={}'.format(check))
            print()


# test_base32()
# test_string = '}Ahb1Lj $!fGDz|?o*`;V^/Fi7J8)'
test_string = 'OB'
test = string_2_base32(test_string)
check = base64.b32encode(test_string.encode('utf-8')).decode('utf-8')

print('string={}'.format(test_string))
print('{}'.format(test))
print('{}'.format(check))
# print(test, check)
